package ex14.pyrmont.startup;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.connector.http.HttpConnector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.core.StandardServer;
import org.apache.catalina.core.StandardService;
import org.apache.catalina.core.StandardWrapper;
import org.apache.catalina.loader.WebappLoader;

import ex14.pyrmont.core.SimpleContextConfig;

public final class Bootstrap {
	public static void main(String[] args) throws Exception {

		System.setProperty("catalina.base", System.getProperty("user.dir"));
		HttpConnector connector = new HttpConnector();

		StandardWrapper wrapper1 = new StandardWrapper();
		wrapper1.setName("Primitive");
		wrapper1.setServletClass("PrimitiveServlet");
		StandardWrapper wrapper2 = new StandardWrapper();
		wrapper2.setName("Modern");
		wrapper2.setServletClass("ModernServlet");

		StandardContext context = new StandardContext();
		// StandardContext's start method adds a default mapper
		context.setPath("/app1");
		context.setDocBase("myApp");

		context.addChild(wrapper1);
		context.addChild(wrapper2);

		LifecycleListener listener = new SimpleContextConfig();
		((Lifecycle) context).addLifecycleListener(listener);

		StandardHost host = new StandardHost();
		host.addChild(context);
		host.setName("localhost");
		host.setAppBase("WebRoot");

		WebappLoader loader = new WebappLoader();
		context.setLoader(loader);
		// context.addServletMapping(pattern, name);
		context.addServletMapping("/Primitive", "Primitive");
		context.addServletMapping("/Modern", "Modern");

		StandardEngine engine = new StandardEngine();
		engine.addChild(host);
		engine.setDefaultHost("localhost");

		StandardService service = new StandardService();
		service.setName("Stand-alone Service");
		service.addConnector(connector);

		// StandardService class's setContainer will call all its connector's
		// setContainer method
		service.setContainer(engine);

		StandardServer server = new StandardServer();
		server.addService(service);

		// Start the new server
		if (server instanceof Lifecycle) {
			try {
				server.initialize();
				(server).start();
				server.await();
				// the program waits until the await method returns,
				// i.e. until a shutdown command is received.
			} catch (LifecycleException e) {
				e.printStackTrace(System.out);
			}
		}

		System.in.read();
		// Shut down the server
		if (server instanceof Lifecycle) {
			try {
				((Lifecycle) server).stop();
			} catch (LifecycleException e) {
				e.printStackTrace(System.out);
			}
		}
	}
}